﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Data;
using System.Reflection;
using System.Runtime.Serialization;
using MyBasicLib.Reflection;
using System.Runtime.InteropServices;

namespace MyBasicLib.Extensions
{
    public static class DataRecordExtensions
    {
       

        public static T ToModel<T>(this IDataRecord reader)  
        {
            T t = default(T);
           // return t;
            Type type = typeof(T);
            if (type.Namespace == "System")
            {
                object obj = reader.GetValue(0);
                return obj is DBNull ? default(T) : (T)obj;
            }
            MyConstructorInfo ctor = TypeDataCache.GetTypeData<T>().GetConstructorInfo();
            if (type.IsAnonymousType())
            {
                object[] values;
                values = new object[reader.FieldCount];
                reader.GetValues(values);
                for (int i = 0; i < values.Length; i++)
                {
                    if (values[i] is DBNull)
                        values[i] = null;
                }
            
                t = (T)ctor.FastInvoke(values);
                return t;
            }


            //  t = (T) FormatterServices.GetUninitializedObject(type); 
            t = (T)ctor.FastInvoke(new object[0]);

            object[] objs = new object[reader.FieldCount];


            int length = reader.GetValues(objs);
            for (int i = 0; i < length; i++)
            { 
                object obj = objs[i];
                if (obj==DBNull.Value) continue;             
         
                string name = reader.GetName(i);
                var pi = TypeDataCache.GetTypeData<T>().GetPropertyInfo(name);

                if (pi == null) continue;
                pi.FastSetValue(t, obj);
            }
            //for (int i = 0; i < pros.Length; i++)
            //{
            //    var idx = reader.GetOrdinal(pros[i].Name);
            //    if (idx < 0) continue;
            //    var obj = reader.GetValue(idx);
            //    if (obj is DBNull) continue;
            //    pros[i].FastSetValue(t, obj);
            //}
            return t;
        }
    }
}